package com.jy.adscm.utils;

import com.jy.adscm.bean.system.JyUser;
import com.jy.adscm.exception.AdscmSystemException;
import com.jy.adscm.security.utils.Token;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author yyy
 * @ClassName StringUtils
 * @Description 工具类
 * @date 2018/7/26 19:12
 */
public class AdscmBaseUtils {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private AdscmBaseUtils(){}
    private static AdscmBaseUtils stringUtils;

    public static AdscmBaseUtils getInstance(){
        synchronized (AdscmBaseUtils.class){
            if (stringUtils == null){
                stringUtils = new AdscmBaseUtils();
            }
            return stringUtils;
        }
    }

    /**
     * 在指定的字符串前拼装 指定字符串
     * @param source ：指定字符串
     * @param len：拼装出来的总长度
     * @param addStr：需要拼装的指定字符串
     * @return
     */
    public String addZeroToStr(String source,int len,String addStr){

        StringBuffer buffer = new StringBuffer();
        if (source == null){
            source = "";
        }

        for (int i=0;source != null && buffer.length() < (len - source.length()); i++){
            buffer.append(addStr);
        }

        buffer.append(source);

        return buffer.toString();
    }

//    public static void main(String[] args) {
//        String result = AdscmBaseUtils.getInstance().addZeroToStr(new Integer(1).toString(),3,"a");
//        System.out.println(result);
//    }

    /**
     * 判断一个对象是否为空，如果指定了某个属性，则即使对象不为空，这个对象的这个属性为空，则也返回 true
     * 如果没有指定field属性，则判断对象是否为空
     * @param source
     * @param field
     * @return
     */
    public boolean isNotEmpty(Object source,String field){
        if (source == null || "".equals(source)){
            return false;
        }else{
            if (field == null || "".equals(field)){
                return true;//如果传入的属性值为null，则直接返回对象是否为空
            }else {
                Class clazz = source.getClass();
                try {
                    Field field_ = clazz.getDeclaredField(field);
                    field_.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                    Object obj = field_.get(source);
                    if (obj == null || "".equals(obj)){
                        return false;
                    }else {
                        return true;
                    }

                } catch (NoSuchFieldException e) {
                    logger.error("对象Object["+source+"]没有属性["+field+"],StringUtils.isEmpty()方法返回true...",e);
                    return false;
                } catch (IllegalAccessException e) {
                    logger.error("获取对象Object["+source+"]的属性["+field+"]异常,StringUtils.isEmpty()方法返回true...",e);
                    e.printStackTrace();
                    return false;
                }
            }

        }
    }

    /**
     * 获取请求的IP
     * @param request
     * @return
     */
    public String getIPAddress(HttpServletRequest request) {
        // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址

        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            if("0:0:0:0:0:0:0:1".equals(ip)){
                ip = "127.0.0.1";
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }


    /**
     * 根据tokenID，获取Redis中的token
     * @param tokenId
     * @param tokenRedisTemplate
     * @return
     */
    public Token getTokenByTokenId(String tokenId , RedisTemplate<Object,Token> tokenRedisTemplate){
        synchronized (this){
            if (AdscmBaseUtils.getInstance().isNotEmpty(tokenId,null)){
                logger.info("根据tokenId["+tokenId+"]获取Redis中的Token信息...");

                ValueOperations<Object,Token> vo = tokenRedisTemplate.opsForValue();
                Token token = vo.get(tokenId);

                return token;

            }else {
                return null;
            }
        }
    }

    public void cleanToken(String tokenId , RedisTemplate<Object,Token> tokenRedisTemplate) throws AdscmSystemException{
        try {
            synchronized (this){
                if (AdscmBaseUtils.getInstance().isNotEmpty(tokenId,null)){
                    logger.info("清除tokenId["+tokenId+"]在Redis中的Token信息...");

                    ValueOperations<Object,Token> vo = tokenRedisTemplate.opsForValue();
                    Token token = vo.get(tokenId);
                    if (token != null){
                        JyUser user = token.getUser();

                        tokenRedisTemplate.expire(tokenId,1 , TimeUnit.SECONDS);//设置过期时间
                        tokenRedisTemplate.expire(user.getUsername(),1 , TimeUnit.MILLISECONDS);//设置过期时间
                    }

                }
            }
        }catch (Exception e){
            throw new AdscmSystemException("清除token异常 : " + e.getMessage());
        }
    }

    public String readImgToBase64(String filePath){

        String base64 = "";
        try {
            InputStream inputStream = null;
            byte[] data = null;
            try {
                inputStream = new FileInputStream(filePath);
                data = new byte[inputStream.available()];
                inputStream.read(data);
                inputStream.close();
            } catch (IOException e) {
                logger.error("读取文件【"+filePath+"】异常",e);
            }
            // 加密
            BASE64Encoder encoder = new BASE64Encoder();
            if (data != null){
                base64 = encoder.encode(data);
            }

        }catch (Exception e){
            logger.error("文件【"+filePath+"】转换成Base64字符串异常",e);
        }
        return base64;

    }

    /**
     * 求一个数的相反数
     * @param num
     * @return
     */
    public int getOppositeNum(Integer num){
            if (num == null){
                num = 0;
            }
            return (num * -1);
    }


    /**
     *  复制单个文件
     *  @param  oldPath  String  原文件路径  如：c:/fqf.txt
     *  @param  newPath  String  复制后路径  如：f:/fqf.txt
     *  @return  boolean
     */
    public  void  copyFile(String  oldPath,  String  newPath)  {
        try  {
//           int  bytesum  =  0;
            int  byteread  =  0;
            File  oldfile  =  new  File(oldPath);
            if  (oldfile.exists())  {  //文件存在时
                InputStream  inStream  =  new  FileInputStream(oldPath);  //读入原文件
                FileOutputStream  fs  =  new FileOutputStream(newPath);
                byte[]  buffer  =  new  byte[1444];
//               int  length;
                while  (  (byteread  =  inStream.read(buffer))  !=  -1)  {
//                   bytesum  +=  byteread;  //字节数  文件大小
//                   System.out.println(bytesum);
                    fs.write(buffer,  0,  byteread);
                }
                inStream.close();
            }
        }
        catch  (Exception  e)  {
            System.out.println("复制单个文件操作出错");
            e.printStackTrace();

        }

    }


    /**
     *  删除文件
     *  @param  filePathAndName  String  文件路径及名称  如c:/fqf.txt
     *  @return  boolean
     */
    public  void  delFile(String  filePathAndName)  {
        try  {
            String  filePath  =  filePathAndName;
            filePath  =  filePath.toString();
            java.io.File  myDelFile  =  new  java.io.File(filePath);
            myDelFile.delete();

        }
        catch  (Exception  e)  {
            System.out.println("删除文件操作出错");
            e.printStackTrace();

        }

    }

    /**
     *  移动文件到指定目录
     *  @param  oldPath  String  如：c:/fqf.txt
     *  @param  newPath  String  如：d:/fqf.txt
     */
    public  void  moveFile(String  oldPath,  String  newPath)  {
        copyFile(oldPath,  newPath);
        delFile(oldPath);

    }
}
